<!-- markdown解析 -->
<template>
  <!-- eslint-disable vue/no-v-html -->
  <div
    ref="rootRef"
    v-html="content"
    class="markdown-body"
    @click="handleClick"
  ></div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from "vue";
import { getProcessor } from "bytemd";

defineOptions({ name: "ByteMdViewer" });

const props = defineProps({
  value: String,
  config: Object,
});

/** 根节点 */
const rootRef = ref(null);

/** 解析后内容 */
const content = ref(null);

/** 已绑定的插件 */
const cbs = ref([]);

/** 绑定插件 */
const on = () => {
  if (props.config?.plugins && rootRef.value && content.value) {
    cbs.value = props.config.plugins.map(({ viewerEffect }) => {
      return (
        viewerEffect &&
        viewerEffect({
          markdownBody: rootRef.value,
          file: content.value,
        })
      );
    });
  }
};

/** 解绑插件 */
const off = () => {
  if (cbs.value) {
    cbs.value.forEach((cb) => cb && cb());
  }
};

/** 处理点击事件支持锚点 */
const handleClick = (e) => {
  const $ = e.target;
  if ($.tagName !== "A") {
    return;
  }
  const href = $.getAttribute("href");
  if (!href || !href.startsWith("#")) {
    return;
  }
  const $root = rootRef.value;
  if ($root) {
    const dest = $root.querySelector("#user-content-" + href.slice(1));
    if (dest) {
      dest.scrollIntoView();
    }
  }
};

// 解析
watch(
  [() => props.value, () => props.config],
  () => {
    try {
      content.value = getProcessor(Object.assign({}, props.config)).processSync(
        props.value,
      );
    } catch (e) {
      console.error(e);
    }
    off();
    nextTick(() => {
      on();
    });
  },
  {
    immediate: true,
    deep: true,
  },
);

onMounted(() => {
  on();
});

onBeforeUnmount(() => {
  off();
});
</script>
